﻿using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System.Xml;
using Formatting = Newtonsoft.Json.Formatting;

namespace HelperFromTheSkeleton.Convert
{
    /// <summary>
    /// Json转换类
    /// </summary>
    public static class JsonConvert
    {
        /// <summary>
        /// 对象转object
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string ToJson(this object obj)
        {
            JsonSerializerSettings? jsonSerializerSettings = new()
            {
                NullValueHandling = NullValueHandling.Ignore,
                DateFormatString = "yyyy-MM-ddTHH:mm:ss.ffffZ"

            };
            return Newtonsoft.Json.JsonConvert.SerializeObject(obj, jsonSerializerSettings);
        }

        /// <summary>
        /// 对象转object
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string ToJsonOrderByPropertyName(this object obj)
        {
            JsonSerializerSettings? jsonSerializerSettings = new()
            {
                NullValueHandling = NullValueHandling.Ignore,
                DateFormatString = "yyyy-MM-ddTHH:mm:ss.ffffZ",
                ContractResolver = new SortContractResolver()

            };
            return Newtonsoft.Json.JsonConvert.SerializeObject(obj, jsonSerializerSettings);
        }

        /// <summary>
        /// Json转对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="str"></param>
        /// <returns></returns>
        public static T? ToObject<T>(this string str)
        {
            var jSetting = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.Indented, };
            return Newtonsoft.Json.JsonConvert.DeserializeObject<T>(str.ToString(), jSetting);
        }

        /// <summary>
        /// Json转对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="str"></param>
        /// <returns></returns>
        public static object? ToObject(this string str, Type type)
        {
            var jSetting = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.Indented, };
            return Newtonsoft.Json.JsonConvert.DeserializeObject(str.ToString(), type, jSetting);
        }

        /// <summary>
        /// Json串转换为XML字符串
        /// </summary>
        /// <param name="strJson"></param>
        /// <returns></returns>
        public static string JsonToXml(this string strJson)
        {
            if (!IsJson(strJson)) throw new InvalidOperationException("不是有效的Json字符串");
            var xml = Newtonsoft.Json.JsonConvert.DeserializeXmlNode(strJson);
            return xml?.InnerXml ?? "";
        }

        /// <summary>
        /// XML字符串转换为Json串
        /// </summary>
        /// <param name="strXml"></param>
        /// <returns></returns>
        public static string XmlToJson(this string strXml)
        {
            if (!IsXml(strXml)) throw new InvalidOperationException("不是有效的Xml字符串");
            var xml = new XmlDocument();
            xml.LoadXml(strXml);
            return Newtonsoft.Json.JsonConvert.SerializeXmlNode(xml);
        }

        /// <summary>
        /// 是否是JSON字符串
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static bool IsJson(this string str)
        {
            try
            {
                Newtonsoft.Json.JsonConvert.DeserializeObject(str);
                return true;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 是否是XML字符串
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static bool IsXml(this string str)
        {
            try
            {
                var xml = new XmlDocument();
                xml.LoadXml(str);
                return true;
            }
            catch
            {
                return false;
            }
        }

        public class SortContractResolver : DefaultContractResolver
        {
            protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
            {
                IList<JsonProperty> properties = base.CreateProperties(type, memberSerialization);

                return properties.OrderBy(x => x.PropertyName).ToList();
            }
        }
    }
}